/*
* SousVide.cpp
*
* Created: 23/08/2012 18:31:48
*  Author: Richard

* MAX7221CNG Wiring Details
*
* MAX7221 - Arduino - Function
*
*/

#define F_CPU 16000000
#define ARDUINO 100

#include <Arduino.h>

#include "LedControl.h"
#include "PID_v1.h"
#include "timer.h"

#define RELAY_PIN 5
#define BUTTON_1_PIN 2
#define BUTTON_2_PIN 3
#define LED_PIN 4

#define BUTTON_1_BIT 0
#define BUTTON_2_BIT 1

#define WINDOW_SIZE 5000		/* PWM Cycle Time (s) */

#define DISPLAY_MODE_SET 1		/* constants for display mode - this should really be an enum */
#define DISPLAY_MODE_READ 0

#define DISPLAY_MODE_TIMEOUT 6  /* number of timer1 periods prior to the screen returning to the current temperature */
#define DISPLAY_UPDATE_COUNT_MAX 200 /* number of runs of counter 2 before triggering a display update */

volatile int setTemperature = 600;	/* 10 times the set temperature */
volatile int reading;				/* reading from the ADC */
volatile int tempC;					/* 10 times the current temperature */

/* PID controller variables */

double setPoint;
double input;
double output;

PID myPID(&input, &output, &setPoint, 2, 5, 1, DIRECT);

volatile byte buttonState = 0;		/* holds the state of the buttons - 1 bit for each button - constants above */
volatile int buttonHeld = 0;
	
int displayMode = DISPLAY_MODE_SET;
int displayTimeout = 0;
volatile int displayUpdateCount = 0; /* number of cyles of counter2 since last display update */

void printNumber( int );
void updateDisplay();

LedControl led1=LedControl(11,13,10,1);

void buttonOneEvent() {
	int value;
	value = digitalRead(BUTTON_1_PIN);
		if (value == HIGH) { // button pressed
		buttonState |= (1 << BUTTON_1_BIT);
	} else { // button released
		buttonState &= ~(1 << BUTTON_1_BIT);
		setTemperature++;
	}
	displayMode = DISPLAY_MODE_SET;
	displayTimeout = DISPLAY_MODE_TIMEOUT;
	
	updateDisplay();
}

void buttonTwoEvent() {
	int value = 0;
	value = digitalRead(BUTTON_2_PIN);
	if (value == HIGH) { // button pressed
		buttonState |= (1 << BUTTON_2_BIT);
	} else { // button released
		buttonState &= ~(1 << BUTTON_2_BIT);
		setTemperature--;
	}	
	displayMode = DISPLAY_MODE_SET;
	displayTimeout = DISPLAY_MODE_TIMEOUT;
	
	updateDisplay();
}

void printInt(int v) {
	int ones;
	int tens;
	int hundreds;
	
	if (v < 0 || v > 999)
		return;
	
	ones = v % 10;
	v = v / 10;
	tens = v % 10;
	v = v / 10;
	hundreds = v;

	//Now print the number digit by digit
	led1.setDigit(0,1,(byte)hundreds,false);
	led1.setDigit(0,2,(byte)tens,true);
	led1.setDigit(0,3,(byte)ones,false);
}

void updateDisplay() {
	switch (displayMode) {
		case DISPLAY_MODE_READ:
			printInt(tempC);
			digitalWrite(4,0);
			break;
		case DISPLAY_MODE_SET:
			printInt(setTemperature);
			digitalWrite(4,1);
			break;
	}
}

ISR(TIMER1_COMPA_vect) {
}

ISR(TIMER1_OVF_vect) {		
}

ISR(TIMER2_COMPA_vect) {
	if (displayUpdateCount >= DISPLAY_UPDATE_COUNT_MAX) {
		displayUpdateCount = 0;
		switch (buttonState) {
/*			case 1: // BUTTON_ONE
				displayTimeout = DISPLAY_MODE_TIMEOUT;
				setTemperature += 10; updateDisplay();
				break;
			case 2: // BUTTON_TWO
				displayTimeout = DISPLAY_MODE_TIMEOUT;
				setTemperature -= 10; updateDisplay();
				break;
			case 3: // BUTTON_ONE & BUTTON_TWO
				displayTimeout = DISPLAY_MODE_TIMEOUT;
				Serial.println("Both Buttons Held");
				break; */ /* commented out cause its a bit broken */
			default: // No buttons are pressed
				reading = analogRead(0);
				tempC = (int)((float)reading / .931);
				if (displayTimeout) {
					displayMode = DISPLAY_MODE_SET;
					displayTimeout--;
				} else {
					displayMode = DISPLAY_MODE_READ;
				}
				updateDisplay();
		}; /* end switch(buttonState) */
	} else {
		displayUpdateCount++;
	}	/* end if(display_count_max <= DISPLAY_COUNT_MAX) */
} /* end function */

void setup() {
	Serial.begin(9600);
	Serial.println("Initializing Interrupt Handler");

	pinMode(LED_PIN, OUTPUT);
	pinMode(BUTTON_1_PIN, INPUT);
	pinMode(BUTTON_2_PIN, INPUT);

	attachInterrupt(0, buttonOneEvent, CHANGE);
	attachInterrupt(1, buttonTwoEvent, CHANGE);
	
	analogReference(INTERNAL);
	
	led1.setScanLimit(0,3);
	led1.setIntensity(0,4);
	led1.shutdown(0,false);
	led1.clearDisplay(0);
	
	startTimerOne();
	startTimerTwo();
	
	displayMode = DISPLAY_MODE_READ;
	
	updateDisplay();
}

void loop () {
	
}